package com.skymxc.processor;

import com.skymxc.annotation.OnClick;
import com.skymxc.annotation.OnLongClick;

import java.lang.annotation.ElementType;
import java.util.LinkedHashSet;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.tools.Diagnostic;

/**
 * click 注解处理器
 */
public class ClickAnnotationProcessor extends AbstractProcessor {
    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> stringSet = new LinkedHashSet<>();
        stringSet.add(OnClick.class.getCanonicalName());
        stringSet.add(OnLongClick.class.getCanonicalName());
        return stringSet;
    }

    /**
     * 动态生成 OnClickListener 包装类，内部含有标注 @OnClick,@OnLongClick 的 method，在内部实现反射调用
     * 类似于纯反射调用，只不过包装类是编译时由程序创建，而不是手动创建。
     * @param annotations
     * @param roundEnv
     * @return
     */
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        if (annotations.isEmpty()) return false;//已经处理过了
        for (TypeElement element:annotations){
            note("annotation->"+element.getQualifiedName());
        }
        Elements elementUtils = processingEnv.getElementUtils();
        Set<? extends Element> clickElement = roundEnv.getElementsAnnotatedWith(OnClick.class);
        if (!clickElement.isEmpty()){
            for (Element element:clickElement){
                String packageName = elementUtils.getPackageOf(element).getQualifiedName().toString();
                note(element.getSimpleName()+" 的包名是："+packageName);
                OnClick annotation = element.getAnnotation(OnClick.class);
                if (element.getKind()== ElementKind.METHOD){
                    ExecutableElement executableElement = (ExecutableElement) element;
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,element.getSimpleName()+" is ExecutableElement");
                    //包含它的元素，也就是类
                    Element enclosingElement = executableElement.getEnclosingElement();
                    if (enclosingElement.getKind()==ElementKind.CLASS){
                        TypeElement elementType = (TypeElement) enclosingElement;
                        note(element.getSimpleName()+".getEnclosingElement 是一个类："+elementType.getQualifiedName());
                    }
                }else{
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,element.getSimpleName()+" is "+element.getKind());
                }
            }
        }

        Set<? extends Element> longClickElement = roundEnv.getElementsAnnotatedWith(OnLongClick.class);
        return true;
    }


    private void note(String msg){
        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,msg);
    }

    private void error(String msg,Element element){
        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,msg,element);
    }


}